package cn.ymjr.sys.util;


import org.apache.commons.lang.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 *
 *  日期工具类
 */
public class DateUtil {
    /*带毫秒日期时间格式*/
    public static final String FORMAT_FULL_DATE_TIME = "yyyy-MM-dd HH:mm:ss SSS";
    /*日期时分秒格式*/
    public static final String FORMAT_DATE_TIME = "yyyy-MM-dd HH:mm:ss";
    /*日期时分格式*/
    public static final String FORMAT_DATE_HHMM = "yyyy-MM-dd HH:mm";
    /*数据库保存时间格式*/
    public static final String FORMAT_DATE_TIME_DB = "yyyyMMddHHmmss";
    /*日期显示格式*/
    public static final String FORMAT_DATE = "yyyy-MM-dd";
    /*日期显示格式*/
    public static final String FORMAT_DATE_DB = "yyyyMMdd";
    public static final String FORMAT_DATE_MONTH = "yyyyMM";
    /*时间显示格式*/
    public static final String FORMAT_TIME = "HH:mm:ss";
    /*日期格式yyyy/MM/dd*/
    public static final String FORMAT_DATE_SLASH = "yyyy/MM/dd";
    /*小时分钟格式*/
    public static final String FORMAT_HHmm = "HHmm";
    /*年月*/
    public static final String FORMAT_yyyyMM = "yyyy-MM";
    /*Quartz配置格式*/
    public static final String FORMAT_QUARTZ = "ss mm HH dd MM ? yyyy";

    protected static Map<String, DateFormat> converters = null;

    static{
        initialization();
    }

    protected static void initialization(){
        if(converters == null){
            converters = new Hashtable<String, DateFormat>();
            converters.put(FORMAT_FULL_DATE_TIME, new SimpleDateFormat(FORMAT_FULL_DATE_TIME));
            converters.put(FORMAT_DATE_TIME, new SimpleDateFormat(FORMAT_DATE_TIME));
            converters.put(FORMAT_DATE_HHMM, new SimpleDateFormat(FORMAT_DATE_HHMM));
            converters.put(FORMAT_DATE_TIME_DB, new SimpleDateFormat(FORMAT_DATE_TIME_DB));
            converters.put(FORMAT_DATE, new SimpleDateFormat(FORMAT_DATE));
            converters.put(FORMAT_DATE_DB, new SimpleDateFormat(FORMAT_DATE_DB));
            converters.put(FORMAT_DATE_MONTH, new SimpleDateFormat(FORMAT_DATE_MONTH));
            converters.put(FORMAT_TIME, new SimpleDateFormat(FORMAT_TIME));
            converters.put(FORMAT_HHmm, new SimpleDateFormat(FORMAT_HHmm));
            converters.put(FORMAT_QUARTZ, new SimpleDateFormat(FORMAT_QUARTZ));
            converters.put(FORMAT_yyyyMM,new SimpleDateFormat(FORMAT_yyyyMM));
            converters.put(FORMAT_DATE_SLASH,new SimpleDateFormat(FORMAT_DATE_SLASH));
        }
    }

    /**
     * 时间格式相互转换
     * @param datetime 日期时间数据
     *
     * @param source 源数据格式，如：DateUtil.FORMAT_FULL_DATE_TIME
     *
     * @param target 目标数据格式，如：DateUtil.FORMAT_DATE_TIME
     *
     * @return 目标数据格式的日期时间数据
     *
     * 例：DateUtil.format("2015-11-17 02:02:30", DateUtil.FORMAT_DATE_TIME, FORMAT_DATE)
     * 结果：2015-11-17
     */
    public static String format(String datetime, String source, String target) throws Exception {
       try {
            return converters.get(target).format(converters.get(source).parse(datetime));
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }
    /**
     * 时间转换
     */
    public static String formatLong(Long dateTime){
        if(dateTime!=null){
            String s = String.valueOf(dateTime);
            return s.substring(0,4)+"-"+s.substring(4,6)+"-"+s.substring(6,8)+" "+s.substring(8,10)+":"+s.substring(10,12)+":"+s.substring(12,14);
        }
        return "";
    }
    /**
     *  日期转换为指定的日期时间格式
     *
     * @param datetime 日期时间数据
     *
     * @param target 指定格式
     *
     * @return 返回指定的时间格式字符串
     */
    public static String format(Date datetime, String target) throws Exception {
        try{
            return converters.get(target).format(datetime);
        }catch(Exception e){
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 字符转转换为Date格式
     *
     * @param datetime 字符串形的日期时间数据
     *
     * @param converter 字符串形数据的格式
     *
     * @return 日期型结果
     */
    public static Date parse(String datetime, String converter) throws Exception {
        try {
            return converters.get(converter).parse(datetime);
        } catch (ParseException e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 将字符型日期转换为数据库格式
     * @param datetime  字符型日期
     * @param converter 字符型日期的格式
     * @return
     */
    public static long formatToDB(String datetime, String converter) throws Exception {
        try {
            return Long.parseLong(converters.get(FORMAT_DATE_TIME_DB).format(converters.get(converter).parse(datetime)));
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    public static String formatToString(long datetime, String converter) throws Exception {
        try {
            return converters.get(converter).format(converters.get(FORMAT_DATE_TIME_DB).parse(String.valueOf(datetime)));
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    public static String defaultToString(Long datetime) throws Exception{
        String dataStr ="";
        if(datetime != null ){
            try {
                dataStr= converters.get(FORMAT_DATE_TIME).format(converters.get(FORMAT_DATE_TIME_DB).parse(String.valueOf(datetime)));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return dataStr;
    }



    /**
     * 获取当前日期 yyyy-mm-dd
     * @return 20151125
     */
    public static long getDefaultDate(){
        return getDbByDate(new Date());
    }

    /**
     * 获取long型日期
     * @param date
     * @return
     */
    public static long getDbByDate(Date date){
        return Long.parseLong(converters.get(FORMAT_DATE_TIME_DB).format(date));
    }

    /**
     * 获取当月时间
     * @return
     */
    public static long getCurMonthForDB(){
        return Long.parseLong(converters.get(FORMAT_DATE_MONTH).format(new Date()));
    }

    public static Integer getCurMonthForDBParseInteger(){
        return Integer.parseInt(converters.get(FORMAT_DATE_MONTH).format(new Date()));
    }
    /**
     * 获取当前时间yyyymmddhhmmss
     * @return yyyymmddhhmmss
     */
    public static long getNowDateTime(){
        return getDbByDate(new Date());
    }
    /**
     * 获取当前时间yyyy-MM-dd
     */
    public static String getNowDateFormat(){
        return converters.get(FORMAT_DATE).format(new Date());
    }

    public static String getNowMonthFormat(){
        return converters.get(FORMAT_yyyyMM).format(new Date());
    }
    /**
     *获取当前时间，字符串格式
     * @return
     */
    public static String getSNowDateTime(){
        return converters.get(FORMAT_DATE_TIME).format(new Date());
    }
    /**
     *获取当前日期不带时间
     * @return
     */
    public static String getSNowDate(){
        return converters.get(FORMAT_DATE_DB).format(new Date());
    }

    /**
     * 获取当前时间yyyymmdd
     * @return yyyymmdd
     */
    public static long getNowDateTimeLong(){
        return Long.parseLong(converters.get(FORMAT_DATE_DB).format(new Date()));
    }

    /**
     * 获取当前时间yyyymmdd
     * @return yyyymmdd
     */
    public static Integer getNowDateTimeInteger(){
        return Integer.parseInt(converters.get(FORMAT_DATE_DB).format(new Date()));
    }

    /**
     * 获取2个时间之间的差值 （取整，小数舍去）
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @param differType  差值单位 1天 2小时 3分钟 4秒
     * @return
     */
    public static long getDifferDate(String startTime, String endTime, String differType){
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long nd = 1000*24*60*60;//一天的毫秒数
        long nh = 1000*60*60;//一小时的毫秒数
        long nm = 1000*60;//一分钟的毫秒数
        long ns = 1000;//一秒钟的毫秒数
        long diff;
        long differCount = 0;
        try {
            //获得两个时间的毫秒时间差异
            diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();
	/*		long day = diff/nd;//计算差多少天
			long hour = diff%nd/nh;//计算差多少小时
			long min = diff%nd%nh/nm;//计算差多少分钟
			long sec = diff%nd%nh%nm/ns;//计算差多少秒
			//输出结果
			//System.out.println("时间相差："+day+"天"+hour+"小时"+min+"分钟"+sec+"秒。");*/
            if("1".equals(differType)){
                differCount = diff/nd;//计算差多少天
                return differCount;
            }
            if("2".equals(differType)){
                differCount = diff/nh;//计算差多少小时
                return differCount;
            }
            if("3".equals(differType)){
                differCount = diff/nm;//计算差多少分钟
                return differCount;
            }
            if("4".equals(differType)){
                differCount = diff/ns;//计算差多少秒
                return differCount;
            }

        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return differCount;
    }
    /**
     * 根据年 月 获取对应的月份 天数
     * */
    public static String[] getDaysByYearMonth(String dateMonth) {
        int maxDate=30;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar calendar = new GregorianCalendar();
        if(StringUtils.isNotEmpty(dateMonth)){
            try {
                Date parse = sdf.parse(dateMonth);
                calendar.setTime(parse);
                maxDate = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else{
            Date date1 = new Date();
            calendar.setTime(date1);
            maxDate = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        }

        String[] dates = new String[maxDate];
        for(int i=0;i<maxDate;i++){
            dates[i] = String.valueOf(i+1);
        }
        return dates;
    }

    /**
     * 根据当前时间获取下一个时间点
     *
     * @param differCount 间隔时间（单位：秒）“可以为负数，负数则时间往前推”
     * @param differType  差值单位 0月 1天 2小时 3分钟 4秒
     * @return
     */
    public static Long getNextDate(int differCount,String differType){
        Calendar ca   =   Calendar.getInstance(); //获取当前时间

        if("0".equals(differType)){//月
            ca.add(Calendar.MONTH, differCount);
        }
        if("1".equals(differType)){//天
            ca.add(Calendar.DAY_OF_YEAR, differCount);
        }
        if("2".equals(differType)){//小时
            ca.add(Calendar.HOUR, differCount);
        }
        if("3".equals(differType)){//分钟
            ca.add(Calendar.MINUTE, differCount);
        }
        if("4".equals(differType)){//秒
            ca.add(Calendar.SECOND, differCount);
        }
        return   Long.parseLong(converters.get(FORMAT_DATE_TIME_DB).format(ca.getTime()));
    }

    /**
     * 根据传入的年份和月份获得该月份的天数
     *
     * @param month
     *            月份-正整数
     * @return 返回天数
     */
    public static  int getDayNumber(Integer month) {
        String monthnew = month + "";
        String yearString = monthnew.substring(0, 4);
        String monthString = monthnew.substring(4, 6);
        int year = Integer.parseInt(yearString);
        int monthNew = Integer.parseInt(monthString);
        int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (2 == monthNew && 0 == (year % 4) && (0 != (year % 100) || 0 == (year % 400))) {
            days[1] = 29;
        }
        return (days[monthNew - 1]);
    }
    /**
     *获取当前时间，字符串格式
     * @return
     */
    public static String getSNowDateTimeDB(){
        return converters.get(FORMAT_DATE_TIME_DB).format(new Date());
    }

    public static List<String> addDates(String cntDateBeg, String cntDateEnd) {
        List<String> list = new ArrayList<>();
        //拆分成数组
        String[] dateBegs = cntDateBeg.split("-");
        String[] dateEnds = cntDateEnd.split("-");
        //开始时间转换成时间戳
        Calendar start = Calendar.getInstance();
        start.set(Integer.valueOf(dateBegs[0]), Integer.valueOf(dateBegs[1]) - 1, Integer.valueOf(dateBegs[2]));
        Long startTIme = start.getTimeInMillis();
        //结束时间转换成时间戳
        Calendar end = Calendar.getInstance();
        end.set(Integer.valueOf(dateEnds[0]), Integer.valueOf(dateEnds[1]) - 1, Integer.valueOf(dateEnds[2]));
        Long endTime = end.getTimeInMillis();
        //定义一个一天的时间戳时长
        Long oneDay = 1000 * 60 * 60 * 24l;
        Long time = startTIme;
        //循环得出
        while (time <= endTime) {
            list.add(new SimpleDateFormat("yyyy-MM-dd").format(new Date(time)).substring(5));
            time += oneDay;
        }
        return list;
    }
    public static List<String> getAllMonth(String startTime,String endTime)throws Exception {
        Date startDate = new SimpleDateFormat("yyyy-MM").parse(startTime);
        Date endDate = new SimpleDateFormat("yyyy-MM").parse(endTime);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        // 获取开始年份和开始月份
        int startYear = calendar.get(Calendar.YEAR);
        int startMonth = calendar.get(Calendar.MONTH);
        // 获取结束年份和结束月份
        calendar.setTime(endDate);
        int endYear = calendar.get(Calendar.YEAR);
        int endMonth = calendar.get(Calendar.MONTH);
        //
        List<String> list = new ArrayList<String>();
        for (int i = startYear; i <= endYear; i++) {
            String date = "";
            if (startYear == endYear) {
                for (int j = startMonth; j <= endMonth; j++) {
                    if (j < 9) {
                        date = i + "-0" + (j + 1);
                    } else {
                        date = i + "-" + (j + 1);
                    }
                    list.add(date);
                }

            } else {
                if (i == startYear) {
                    for (int j = startMonth; j < 12; j++) {
                        if (j < 9) {
                            date = i + "-0" + (j + 1);
                        } else {
                            date = i + "-" + (j + 1);
                        }
                        list.add(date);
                    }
                } else if (i == endYear) {
                    for (int j = 0; j <= endMonth; j++) {
                        if (j < 9) {
                            date = i + "-0" + (j + 1);
                        } else {
                            date = i + "-" + (j + 1);
                        }
                        list.add(date);
                    }
                } else {
                    for (int j = 0; j < 12; j++) {
                        if (j < 9) {
                            date = i + "-0" + (j + 1);
                        } else {
                            date = i + "-" + (j + 1);
                        }
                        list.add(date);
                    }
                }
            }
        }
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                // 返回相反的compare
                return o1.compareTo(o2);
            }
        });
        return list;
    }
    /*public static void main(String args[])throws Exception{
        List<String> strings = getAllMonth("2020-01", "2020-08");
        strings.forEach(i ->
                System.out.println(i)
        );
    }*/
}
